/****************************************************************
 * I am the AC 130 vs Pirate game. I allow the user to control an 
 * AC130 gunship in the hunt for Modern day pirates. The player  
 * will be allowed to roam free across a section of ocean/coastline.  
 * In the water there will be four types of vessels: Merchant  
 * ships that the player must protect, Pirate ships that the player  
 * must identify and destroy, Fishing boats that look like Pirate  
 * ships that the player must not destroy, and Friendly Navy ships  
 * that can capture pirates for extra points. Time permitting there  
 * may also be ground targets to attack. 
 *
 * Key elements of this project will be the Player/AC130, the Ships,  
 * the ShipAI system, the collision grid, the debris controller, the  
 * Ground/Water, Clouds, and scoring system. This project will make  
 * use of an external text file to store useful game parameters,  
 * thus allowing us to play balance the game without recompiling  
 * the executable. 
 ******************************File********************************
 * I am the screen controll funtion. Due to the variety of screens 
 * in this program I manage the active screen and passive screens.
 * and am responsible for passing information to the appropriate 
 * screens.
 ******************************************************************/


#include "ScreenCtrl.h"


/// I am the constructor. I initilize all the screens and global objects
/// I also pass the global object to the appropriate screens.
ScreenCtrl::ScreenCtrl(){
		// set render area to standard 4x3 ratio
	myScreen = create_bitmap(1024, 768);
	gd = new GameData;
		// create screens
	myIntro = new scIntro;
	myIntro->Init(gd);
	myMainMenu = new BaseScreen;
	myMainMenu->Init(gd);
	myGamePlay = new BaseScreen;
	myGamePlay->Init(gd);

		// initilize first screen
	curScreen = myIntro;
	gd->nxtScreen = curScreen->myScreenType;
	isDebug = true;
}


/// I am the destructor. I clean up all internal objects
ScreenCtrl::~ScreenCtrl(){
	destroy_bitmap(myScreen);
	
	delete(myIntro);
	delete(myMainMenu);
	delete(myGamePlay);
	delete(gd);
}

/// I am the update function. I run the regular updates that 
/// facilitate animation and gameplay. I invoke the update and
/// user input functions of the active screen. If the active
/// screen chainges the global active screen pointer
void ScreenCtrl::Update(){
	// process key codes
	for(int itor =0; itor < KEY_MAX; itor++){
		if(key[itor] && gd->oldKey[itor] == false)
			curScreen->OnKeyDn(itor);
		if(key[itor] && gd->oldKey[itor] == true)
			curScreen->OnKeyUp(itor);
	}
		// special case use Tilde to swap debug console
	if( key[KEY_TILDE] && gd->oldKey[KEY_TILDE] ==false){
		isDebug = !isDebug;
	}
		// save oldKey for next iteration
	for(int itor =0; itor < KEY_MAX; itor++){
		gd->oldKey[itor] = key[itor];
	}
		// save mouse location to Game Data as its
		// relative position in the screen
	gd->mouseX = mouse_x*myScreen->w/SCREEN_W;
	gd->mouseY = mouse_y*myScreen->h/SCREEN_H;

		// check mouse buttons
	if( (mouse_b & 1) && gd->lmouse == false) 
		curScreen->OnMouseDn(gd->mouseX, gd->mouseY, 1);
	if( !(mouse_b & 1) && gd->lmouse == true) 
		curScreen->OnMouseUp(gd->mouseX, gd->mouseY, 1);
	if( (mouse_b & 2) && gd->rmouse == false) 
		curScreen->OnMouseDn(gd->mouseX, gd->mouseY, 2);
	if( !(mouse_b & 2) && gd->rmouse == true) 
		curScreen->OnMouseUp(gd->mouseX, gd->mouseY, 2);
	
		// save old mouse values
	gd->lmouse = (mouse_b & 1);
	gd->rmouse = (mouse_b & 2);

		// update current screen now that the input has been handled
	curScreen->Update();
		// check for screen swap
	Swap();
}

/// I am the screen swap function. I run the closing function 
/// of the screen about to be swapped out, and run the opening
/// function of the screen about to be activated. I also set
/// the curScreen to the new screen when done.
void ScreenCtrl::Swap(){
		// check if we don't need to swap Screens
	if( curScreen->myScreenType == gd->nxtScreen) return;
		// now we have to do the screen swap
		// remember old screen
	BaseScreen* oldScreen = curScreen;
	BaseScreen* nxtScreen = curScreen;
		// find new screen
	switch(gd->nxtScreen){
		case stIntro:
			nxtScreen = myIntro;	// impliment later
		break;
		case stMainMenu:
			nxtScreen = myMainMenu;	// impliment later
		break;
		case stGamePlay:
			nxtScreen = myGamePlay;	// fix later
		break;
	}
		// make sure we are actualy swapping screens
	if(oldScreen == nxtScreen) return;
		// run start function on new screen
	nxtScreen->OnStart();
	curScreen = nxtScreen;
	oldScreen->OnClose();
		// Ensure curScreen->myScreenType == gd->nxtScreen. 
		// for next iteration
	curScreen->myScreenType = gd->nxtScreen;
		// screen swap complete
	return;
}


/// I am the draw function. I call the active screen's render
/// funciton. When I am completed the Camera's screen should have
/// the image from the active screen
void ScreenCtrl::Draw(){
		// render screen
	curScreen->Draw(myScreen);
		// render debug text if toggle is on
	if(isDebug){
		textout_ex(myScreen, font, gd->debugTxt, 1, 1,
			makecol(0, 255, 0), makecol(0, 0, 0));
	}
		// blit bufffer to screen
	stretch_blit(myScreen, screen,
		0, 0, myScreen->w, myScreen->h,
		0, 0, screen->w, screen->h);

}